package model;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databeans.MultipleChoiceq;
import interfas.MultipleChoiceqInterface;

public class MultipleChoiceqDAO implements MultipleChoiceqInterface {

	private BeanFactory<MultipleChoiceq> factory;
	
	public MultipleChoiceqDAO() throws DAOException {
		try {
			BeanTable<MultipleChoiceq> table = BeanTable.getInstance(MultipleChoiceq.class, "multiplechoiceq");
			if (!table.exists())
				table.create("qid", "pos");
			
			table.setIdleConnectionCleanup(true);
			factory = table.getFactory();
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(MultipleChoiceq mcq, QuestionDAO questionDAO) throws DAOException {
		try {
			// Check for foreign key constraint
			if (questionDAO.lookup(mcq.getQid()) == null) {
				throw new DAOException("qid must exist in question table");
			}
			
			Transaction.begin();
			MultipleChoiceq dbmcq = factory.create(mcq.getQid(), mcq.getPos());
			factory.copyInto(mcq, dbmcq);
			Transaction.commit();
		} catch (DuplicateKeyException e) {
			throw new DAOException("A multiplechoiceq with qid " + mcq.getQid() + " and pos " + mcq.getPos() + " already exists");
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public MultipleChoiceq lookup(int qid, int pos) throws DAOException {
		try {
			return factory.lookup(qid, pos);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public MultipleChoiceq[] getChoicesByQid(int qid) throws DAOException {
		try {
			return factory.match(MatchArg.equals("qid", qid));
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	//Network (Rank order) version of getChoicesByQid. Based on invariant that there is only one entry for network version.
	public MultipleChoiceq getChoicesByQidRO(int qid) throws DAOException {
		try {
			MultipleChoiceq[] mcq = getChoicesByQid(qid);
			if (mcq.length != 1)
				throw new RollbackException("Invariant violation of length == 1");
			return mcq[0];
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public void delete(int qid, int pos) throws DAOException {
		try {
			Transaction.begin();
			MultipleChoiceq dbmc = lookup(qid, pos);
			if (dbmc == null)
				throw new DAOException("MultipleChoiceq with qid " + qid + " and pos " + pos + " doesn't exist");
			factory.delete(qid);
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public int size() throws DAOException {
		try {
			return factory.getBeanCount();
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
}
